<?php


namespace App\Services;


use App\Exceptions\ApiException;
use App\Exceptions\BaseException;
use App\Models\Config;
use App\Models\MemberOther;
use App\Models\MemberQnRisk;
use App\Models\Order;
use App\Models\OrderDlzwRisk;
use App\Models\OrderThreeElements;
use App\Models\OtherRiskLog;
use App\Models\SaleUser;
use Illuminate\Auth\Events\Validated;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use PhpOffice\PhpWord\TemplateProcessor;

class RiskDlzwService
{
    public static $connectTimeout = 30;//30 second
    public static $readTimeout = 80;//80 second
    const HOST_URL = 'https://cattle.beix.cc/open/api/v1/data';
    const ProjectId = '诺明网络';
    const ProjectScert = 'YC02p9J0lx24n4D8UnX31nGfNul16mNbuT2ADfHZumig60QhSk7H5IhvMYj6LSKs';
    const rsa_public_key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhEZ8E2pkFpBgfWhhEUKO5vqF532dhxzxDUuLbKAU/j66pc/ujEL2M97bSCqe+FxPMKYnRfkaL8JDEY6oSYLCoq6Bv/GWEj+TGraqQpqYkvBA1a+bi3NyletoEWq/FkCpVibd9KS5oHP9knG322YixYhb4nvaGyZ1V+43OsqyuaRR7eKZdysEu9fWCOLLHlt59/KeXdE5kNTY/CFc8oCspkAte6Ihfun1SoiWKj+2H5WMfxvuiLzHgshTXn71DjzapFKiytC0A7jstiGpLCKkg9s4X0lDRA26ZOi/IzaLdQQefRHYvj6F3EncTAFSmkxWhpxojA6CC71vrFRQU3UF6QIDAQAB';
    const rsa_private_key = 'MIIEowIBAAKCAQEAhEZ8E2pkFpBgfWhhEUKO5vqF532dhxzxDUuLbKAU/j66pc/ujEL2M97bSCqe+FxPMKYnRfkaL8JDEY6oSYLCoq6Bv/GWEj+TGraqQpqYkvBA1a+bi3NyletoEWq/FkCpVibd9KS5oHP9knG322YixYhb4nvaGyZ1V+43OsqyuaRR7eKZdysEu9fWCOLLHlt59/KeXdE5kNTY/CFc8oCspkAte6Ihfun1SoiWKj+2H5WMfxvuiLzHgshTXn71DjzapFKiytC0A7jstiGpLCKkg9s4X0lDRA26ZOi/IzaLdQQefRHYvj6F3EncTAFSmkxWhpxojA6CC71vrFRQU3UF6QIDAQABAoIBACVekGEf1oT1Zv0nBv1MU3j33+qld2Kbj5JU/F/E3glyCWMc2mTv6gR/em3p9J1v3sN8vW2sUXSaqj4EkpCqC3jQWkGy69Xd9h4+6t0ENgSVMYvtH8GG7SFjrzP0d2W/ANghBOW/v92Px1yfGfU25q3ttx/GI7k15ULhPuMyLsn5MGCPyzOkdY4OpdsOEnjHTD9KLDjVnZjyCpkoWh+/e3HgV6ZXLZWVKWedZrszagpqVKtaUSx6f2KGhtFVCcHXvBcvIq93DkQg4YBmfSNY+phlLp1ydE7oKUy+XrXJ44EOp147MapjJg66/tXr1bmOL0NlpiIKd091nvZedHvWGc0CgYEA+o1mcyqeq0ptEbyTZT+9gqZIs6ETVcxl6QW6mlDSgwiXsEejjuHNKf35eMo1b9fzV0TfJxqsGiGsDovBFtsK0qySocTt9t8BfyQAKebS8IOMEcUsSIESNRGDaa/59oR2YftRahXfkxxIRNFEBsDy22Jam0uYEDqKPeAY5U08lHsCgYEAhya+Gxt0XwysZyqBSnsqUeASewuxrMHaTrMmPciw0Iot7C4UOetRw51Ss5DDXkV4tonZ8GMiAQChI1LAJeubsfQVNJoRubY9XyVQv8YzmCm8oT/TCcIwGcGEAkDNexWpghdHZThLeWU4SDLfiTE/JNBfQkxqF7I+PHVP6UHjW+sCgYAHOcC0nYwJ4JGYq1mM1/O9KtJ567FFDin6OGITRTVs9fh56vb6jeR+y4ZAR4SW/yFTaPcOh6Ri9ImjucANyq9bOALai3VZY0EFy6H9k1yN9x04/fiy9pXx1dl2WM7anyNS3A6TAqJ5+ZzT7z0I/NOEJCf8xodSIH4QHsBZDIsstQKBgEiPom2HVflaIo3ZIkVMzzHaLdHmO2RXR9ANGzD8uQGdzn4JV06pauKtaqOBy4KnpeHLLTmE39LN9bWzTfqN/q+SLnhpZ67fix+0NyBfV4AQmHeyfqm0moKZhTh4dlnpDXMM8IYFrW/lykvpFF7iE9a+EQbVY/iI+CUZjufbOig1AoGBAJoXspD/ZTYP0pR0X0A97WUd2krs+V4+No2/pKffZhZ2UTOi1AmJSUAlr1TmkOrq5w/E9KJDWR0ARq+gI23pvyjAXXu90oBEzE6QSDpNAXS3TreiwB5Di5UUVNBN9yNk6v5rhXzlynRskuhmxFJFMIphoez1T/GHfCUtxiMil/hC';

    public static function shopInquire($post = [])
    {
        if (Redis::get('dlz_shop_chao_sheng_xin_risk_uid' . $post['id'])) {
            return true;
        }
        Redis::setEx('dlz_shop_chao_sheng_xin_risk_uid' . $post['id'], 7200, 1);

        $one= OrderDlzwRisk::where('order_id',$post['id'])->exists();
        if($one){
            return true;
        }
        $array = [
            'name' => $post['cert_name'],
            'id_card' => $post['cert_no'],
            'mobile' => $post['mobile'],
            'trans_no' => $post['trade_no'],
            'area'=>$post['prov'],
            'age'=>getAgeByID($post['cert_no']),
            'custom'=>'chaoshengxin',
        ];
        $encrypt_data= self::rsaEncrypt(json_encode($array, JSON_UNESCAPED_UNICODE), self::rsa_public_key);
        $micrometer = microtime(true); // 获取当前 Unix 时间戳和微秒数
        $milliseconds = round($micrometer * 1000); // 将微秒数转换为毫秒数
        $body = [
            "merchant_id" => "DL0112",
            "encrypt_data" =>$encrypt_data,
            "time_stamp" => $milliseconds,
            "product_code" => "RK_DL2204",
        ];

        $body['sign']= self::getSign(self::ProjectScert,$body);
        $body = json_encode($body,JSON_UNESCAPED_UNICODE);
        $res = http_post(self::HOST_URL, $body, array('Content-Type:application/json'));

        $res = json_decode($res, true);
        self::addLog('都来租等级风控', $array, $res);
        if ($res['code'] == 200) {
            OrderDlzwRisk::insertFlowMember($post['cert_no'],$post['cert_name'],$post['uid'],$post['id'],$res);
            //分配给憨猪猪
            $i=0;
            if($array['age']<=20||$array['age']>=44&&($res['data']['level']=='A'||$res['data']['level']=='B')){
                $i=1;
            }
            if($array['age']<=22||$array['age']>=40&&($res['data']['level']=='C'||$res['data']['level']=='D')){
                $i=1;
            }
            if($res['data']['level']=='E'||$res['data']['level']=='F'){
                $i=1;
            }
            if($i){
                Order::editOrderData(['orderId'=>$post['id'],'seller_id'=>'1753527655']);
            }

            if($res['data']['level']=='A'||$res['data']['level']=='B'||$res['data']['level']=='C'||$res['data']['level']=='D'){
                (new Order)->orderCheckAutoPass($post['id']);
            }

        }

        if($post['location']&&$post['city']&&strpos($post['location'],$post['city'])=== false&&
            $post['location']&&$post['area']&&strpos($post['location'],$post['area'])=== false||
            $post['location']&&$post['prov']&&strpos($post['location'],$post['prov'])=== false
        ){
             RelationVerifyService::ColseOrder($post['id'],'下单定位与收货地址不一致');
        }


        return $res;
    }


    /**
     * @throws BaseException
     */
    public static function otherApiInquire($post = [])
    {
//        $array = [
//            'name' =>'陈常结',
//            'id_card' => '421223198909145414',
//            'mobile' => '19884150069',
//            'trans_no' => '2025062314393839785275',
//            'area'=>'湖北省',
//            'age'=>'35',
////            'custom'=>'chaoshengxin',
//        ];
//        $rsa_public_key=DB::table('sp_other_risk_user')->where('merchant_id',$post['merchant_id'])->value('rsa_public_key');
//        $rsa_private_key=DB::table('sp_other_risk_user')->where('merchant_id',$post['merchant_id'])->value('rsa_private_key');
//
//        var_dump($rsa_public_key);
//        $encrypt_data= self::rsaEncrypt('{"name":"陈常结","id_card":"421223198909145414","mobile":"19884150069","area":"湖北省","age":"35"}', $rsa_public_key);
//        $res=self::rsaDecrypt($encrypt_data,$rsa_private_key);
//
//        dd($res);

        $mRisk=Redis::get('merchant_abide_risk'.$post['merchant_id']);
        if (!$mRisk) {
            $riskUser=DB::table('sp_other_risk_user')->where('merchant_id',$post['merchant_id'])
                ->select('rsa_private_key','id','project_secret')->first();
            if (!$riskUser) {
                throw new ApiException('商户不存在');
            }
            $riskUser=obToArray($riskUser);
            Redis::set('merchant_abide_risk'.$post['merchant_id'],json_encode($riskUser));
            $rsa_private_key=$riskUser['rsa_private_key'];
            $risk_user_id=$riskUser['id'];
            $project_secret=$riskUser['project_secret'];
        }else{
            $mRisk=json_decode($mRisk,true);
            $rsa_private_key=$mRisk['rsa_private_key'];
            $risk_user_id=$mRisk['id'];
            $project_secret=$mRisk['project_secret'];
        }

        $body = [
            "merchant_id" => $post['merchant_id'],
            "encrypt_data" =>$post['encrypt_data'],
            "time_stamp" => $post['time_stamp'],
        ];
        $sign= self::getSign($project_secret,$body);
        if ($sign != $post['sign']){
            throw new ApiException('验签失败');
        }
        $res=self::rsaDecrypt($post['encrypt_data'],$rsa_private_key);
        $userInfo=json_decode($res,true);
        if(!$userInfo['name']||!$userInfo['id_card']||!$userInfo['mobile']||!$userInfo['trans_no']||!$userInfo['area']||
            !$userInfo['age']){
            throw new ApiException('缺少必要参数');
        }


        $array = [
            'name' => $userInfo['name'],
            'id_card' => $userInfo['id_card'],
            'mobile' => $userInfo['mobile'],
            'trans_no' => $userInfo['trans_no'],
            'area'=>$userInfo['area'],
            'age'=>$userInfo['age'],
            'custom'=>'chaoshengxin',
        ];

        $encrypt_data= self::rsaEncrypt(json_encode($array, JSON_UNESCAPED_UNICODE), self::rsa_public_key);
        $micrometer = microtime(true); // 获取当前 Unix 时间戳和微秒数
        $milliseconds = round($micrometer * 1000); // 将微秒数转换为毫秒数
        $body = [
            "merchant_id" => "DL0112",
            "encrypt_data" =>$encrypt_data,
            "time_stamp" => $milliseconds,
            "product_code" => "RK_DL2204",
        ];

        $body['sign']= self::getSign(self::ProjectScert,$body);
        $body = json_encode($body,JSON_UNESCAPED_UNICODE);
        $res = http_post(self::HOST_URL, $body, array('Content-Type:application/json'));

        $res = json_decode($res, true);
        self::addLog('外部调用都来租等级风控', $array, $res);
        $log=(new OtherRiskLog)->insertFlowMember(
            $risk_user_id,
            $userInfo['id_card'],
            $userInfo['name'],
            $userInfo['mobile'],
            $userInfo['trans_no'],
            $userInfo['area'],
            $userInfo['age'],
            $userInfo['custom']??'',
            $res);
        if($log){
            return $res;
        }else{
            throw new ApiException('调用失败');
        }


    }


    /**
     * @param string $accessKeySecret 加密秘钥，由运营商提供，用于对数据加密
     * @param array $param_arr 需要加密数组
     * @param string $charset 字符串编码
     * @return string
     * @throws Exception
     */
    public static function getSign($accessKeySecret, $param_arr, $charset = "UTF-8")
    {
        $text = self::getParamsStr($param_arr);
        $key = mb_convert_encoding($accessKeySecret, $charset);
        $data = mb_convert_encoding($text, $charset);
        $hash = hash_hmac('sha1', $data, $key, true);
        return base64_encode($hash);
    }

    /**
     * 对数组按照键值升序排序，得到要加密的原始字符串(格式：key1value1key2value2key3value3 格式)
     * @param array $map
     * @return string
     */
    public  static function getParamsStr($map)
    {
        $params = [];
        // 按照键值升序排序
        ksort($map);
        foreach ($map as $key => $value) {
            $params[] = $key . $value;
        }
        return implode('', $params);
    }

    // 填充公钥和私钥标记
    public static function addStartEnd($key, $startMarker, $endMarker)
    {
        if (strpos($key, $startMarker) === false) {
            $key = $startMarker . $key;
        }
        if (strpos($key, $endMarker) === false) {
            $key = $key . $endMarker;
        }
        return $key;
    }

    public static function fillPrivateKeyMarker($privateKey)
    {
        return self::addStartEnd($privateKey, "-----BEGIN RSA PRIVATE KEY-----\n", "\n-----END RSA PRIVATE KEY-----");
    }

    public static function fillPublicKeyMarker($publicKey)
    {
        return self::addStartEnd($publicKey, "-----BEGIN PUBLIC KEY-----\n", "\n-----END PUBLIC KEY-----");
    }

    // 加载公钥或私钥
    public static function loadKey($keyStr)
    {
        return openssl_pkey_get_private($keyStr) ?: openssl_pkey_get_public($keyStr);
    }

// RSA加密 (PKCS#1 v1.5)
    public static function rsaEncrypt($data, $publicKeyStr)
    {
        $publicKey = self::loadKey(self::fillPublicKeyMarker($publicKeyStr));
        if (!$publicKey) {
            throw new BaseException("Invalid public key");
        }
        $dataBytes = $data;
        $maxEncryptBlock = 245; // 2048位RSA的最大加密块大小是245字节$encryptedData = '';
        // 分块加密
        $chunks = str_split($dataBytes, $maxEncryptBlock);
        foreach ($chunks as $chunk) {
            $partialEncrypted = '';
            openssl_public_encrypt($chunk, $partialEncrypted, $publicKey, OPENSSL_PKCS1_PADDING);
            $encryptedData .= $partialEncrypted;
        }
// 转换为Base64格式
        return base64_encode($encryptedData);
    }

// RSA解密 (PKCS#1 v1.5)
    public  static  function rsaDecrypt($encryptedData, $privateKeyStr)
    {
            $privateKey =  self::loadKey( self::fillPrivateKeyMarker($privateKeyStr));
            if (!$privateKey) {
                throw new BaseException("Invalid private key");
            }
            $encryptedBytes = base64_decode($encryptedData);
            $decryptedData = '';
        // 分块解密
           $chunks = str_split($encryptedBytes, 256); // 对于2048位RSA，每次解密块大小为256字节
            foreach ($chunks as $chunk) {
                $partialDecrypted = '';
                if (!openssl_private_decrypt($chunk, $partialDecrypted, $privateKey, OPENSSL_PKCS1_PADDING)) {
                    throw new BaseException("Decryption failed, possibly due to incorrect key or corrupted data.");
                  }
                $decryptedData .= $partialDecrypted;
            }

        return $decryptedData;
     }

    public  static function addLog($message, $request = [], $response = [])
    {
        $content = [
            'request' => is_object($request) ? object_array($request) : $request,
            'response' => is_object($response) ? object_array($response) : $response,
        ];
        \Illuminate\Support\Facades\Log::channel("customerinfo")->debug($message, $content);
    }


}
